﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using TlvLib.Packets;

namespace TlvLib.PacketParsers
{
    public class PacketParser : PacketParserBase, IPacketParser
    {
        public override bool CanParse(RawPacket packet)
        {
            return packet.MessageId == PacketType.LicensePlateInfo;
        }

        public override object Parse(RawPacket packet)
        {

            var stream = new MemoryStream(packet.Payload);
            var reader = new MiscUtil.IO.EndianBinaryReader(Config.EndianBitConverter, stream);

            var mb = reader.ReadBytes(32);//监控点编号
            var count = CountNonZero(mb);
            var m = AsciiEncoding.GetString(mb, 0, count);

            var db = reader.ReadBytes(8);
            count = CountNonZero(db);
            var dir = AsciiEncoding.GetString(db, 0, count);//方向
            var c = reader.ReadInt32();//相机编号
            var r = reader.ReadInt32();//道路编号

            var buffer = reader.ReadBytes(16);
            count = CountNonZero(buffer);
            var plate = GbkEncoding.GetString(buffer, 0, count);//车牌号码

            var x = reader.ReadInt32();//车牌位置
            var y = reader.ReadInt32();
            var w = reader.ReadInt32();
            var h = reader.ReadInt32();

            var confidence = reader.ReadInt32();//车牌识别置信度
            var pColor = reader.ReadInt16();//车牌颜色
            var carType = reader.ReadInt16();//车类
            var carColor = reader.ReadInt16();//车身颜色
            var detectMethod = reader.ReadByte();//检测方式

            var isViolation = reader.ReadByte();//是否违章
            var readLightBeginTime = ReadTime(reader);//红灯开始时间

            var violationBytes = reader.ReadBytes(32);//违章类型
            count = CountNonZero(violationBytes);
            var violationType = AsciiEncoding.GetString(violationBytes, 0, count);

            var speed = reader.ReadInt32();//车速
            var speedLimit = reader.ReadInt32();//速度限制
            var packIdBuffer = reader.ReadBytes(64);//包id
            count = CountNonZero(packIdBuffer);
            var packId = AsciiEncoding.GetString(packIdBuffer, 0, count);

            var imgCount = reader.ReadInt16();//图片数目

            if (imgCount <= 0)
            {
                Log(string.Format("警告，车牌图片数目为 {0}", imgCount));
            }

            var imageDatas = new ImageData[imgCount];
            for (int i = 0; i < imgCount; i++)
            {
                var time = ReadTime(reader);//图片抓拍时间
                var imglen = reader.ReadInt32();//图像长度
                if (imglen <= 0 || imglen > Constants.MaxPacketSize)
                {
                    Log("警告， 图片数据长度为 " + imglen);
                    throw new FormatException("图片长度非法");
                }

                var imgBuffer = reader.ReadBytes(imglen);//图像数据
                if (!Helper.IsValidImageFormat(imgBuffer))
                {
                    Log("图片格式错误");
                    throw new FormatException("图片格式错误");
                }

                imageDatas[i] = new ImageData() { CaptureTime = time, ImageBuffer = imgBuffer };
            }

            var videoCount = reader.ReadByte();//视频数量
            if (videoCount < 0 || videoCount > 10)
            {
                var msg = string.Format("警告，视频数目非法({0})，丢弃该数据", videoCount);
                Log(msg);
                throw new FormatException("视频数目非法，丢弃数据");
            }

            var videos = new VideoData[videoCount];
            for (int i = 0; i < videoCount; i++)
            {
                var beginTime = ReadTime(reader);//视频开始时间
                var endTime = ReadTime(reader);//视频结束时间
                var formatBytes = reader.ReadBytes(5);//视频格式
                count = CountNonZero(formatBytes);
                var format = AsciiEncoding.GetString(formatBytes, 0, count);
                var videoLen = reader.ReadUInt32();//视频长度
                if (videoLen > Constants.MaxPacketSize)
                {
                    Log("视频长度非法，长度为" + videoLen);
                    throw new FormatException("视频长度非法");
                }

                var videoBuffer = reader.ReadBytes((int)videoLen);

                var video = new VideoData();
                video.Begin = beginTime;
                video.End = endTime;
                video.Format = format;
                video.Data = videoBuffer;

                videos[i] = video;
            }


            var lpi = new LicensePlateInfo()
                          {
                              CameraNo = c,
                              Confidence = confidence,
                              IsViolation = isViolation == 1,
                              CarType = carType,
                              Images = imageDatas,
                              MonitorId = m,
                              PlateNo = plate,
                              PlateColor = pColor,
                              PlatePosition = new Rect(x, y, w, h),
                              RedLightBeginTime = readLightBeginTime,
                              RoadNo = r,
                              PacketId = packId,
                              Speed = speed,
                              SpeedLimit = speedLimit,
                              ViolationType = violationType,
                              Videos = videos,
                              DetectMethod = detectMethod,
                              Direction = dir,
                              TimeStamp = DateTime.Now
                          };

            return lpi;
        }
    }
}
